package org.freeocs.action;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.freeocs.Globals;
import org.freeocs.commons.page.PropertyFilter;
import org.freeocs.commons.util.StringUtils;
import org.json.JSONObject;

public abstract class Action {
	protected Log log = LogFactory.getLog(this.getClass());

	public void init(javax.servlet.ServletContext sc) {

	}

	public void render(HttpServletRequest req, HttpServletResponse res, String url) throws ServletException, IOException {
		RequestDispatcher rd = req.getRequestDispatcher(url);
		rd.forward(req, res);
	}

	/**
	 * 直接输出内容的简便函数.
	 * 
	 * eg. render("text/plain", "hello", "encoding:GBK");
	 * render("text/plain","hello", "no-cache:false"); render("text/plain",
	 * "hello", "encoding:GBK","no-cache:false");
	 * 
	 * @param headers
	 *            可变的header数组，目前接受的值为"encoding:"或"no-cache:",默认值分别为UTF-8和true.
	 */
	public void render(final HttpServletResponse resp, final String contentType, final String content, final String... headers) {
		try {
			// 分析headers参数
			String encoding = Globals.ENC_UTF_8;
			boolean noCache = Globals.NOCACHE_DEFAULT;
			for (String header : headers) {
				String headerName = StringUtils.substringBefore(header, ":");
				String headerValue = StringUtils.substringAfter(header, ":");

				if (StringUtils.equalsIgnoreCase(headerName, Globals.ENCODING_PREFIX)) {
					encoding = headerValue;
				} else if (StringUtils.equalsIgnoreCase(headerName, Globals.NOCACHE_PREFIX)) {
					noCache = Boolean.parseBoolean(headerValue);
				} else
					throw new IllegalArgumentException(headerName + "不是一个合法的header类型");
			}

			// 设置headers参数
			String fullContentType = contentType + ";charset=" + encoding;
			resp.setContentType(fullContentType);
			if (noCache) {
				resp.setHeader("Pragma", "No-cache");
				resp.setHeader("Cache-Control", "no-cache");
				resp.setDateHeader("Expires", 0);
			}
			resp.getWriter().write(content);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	/**
	 * 直接输出文本.
	 * 
	 * @see #render(String, String, String...)
	 */
	public void renderText(final HttpServletResponse resp, final String text, final String... headers) {
		render(resp, "text/plain", text, headers);
	}

	/**
	 * 直接输出HTML.
	 * 
	 * @see #render(String, String, String...)
	 */
	public void renderHtml(final HttpServletResponse resp, final String html, final String... headers) {
		render(resp, "text/html", html, headers);
	}

	/**
	 * 直接输出XML.
	 * 
	 * @see #render(String, String, String...)
	 */
	public void renderXml(final HttpServletResponse resp, final String xml, final String... headers) {
		render(resp, "text/xml", xml, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param string
	 *            json字符串.
	 * @see #render(String, String, String...)
	 */
	public void renderJson(final HttpServletResponse resp, final String string, final String... headers) {
		render(resp, "application/json", string, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param map
	 *            Map对象,将被转化为json字符串.
	 * @see #render(String, String, String...)
	 */
	@SuppressWarnings("unchecked")
	public void renderJson(final HttpServletResponse resp, final Map map, final String... headers) {
		String jsonString = new JSONObject(map).toString();
		renderJson(resp, jsonString, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param object
	 *            Java对象,将被转化为json字符串.
	 * @see #render(String, String, String...)
	 */
	public void renderJson(final HttpServletResponse resp, final Object object, final String... headers) {
		String jsonString = new JSONObject(object).toString();
		renderJson(resp, jsonString, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param list
	 *            List对象,将被转化为json字符串.
	 * @see #render(String, String, String...)
	 */
	@SuppressWarnings("unchecked")
	public void renderJson(final HttpServletResponse resp, final List list, final String... headers) {
		String jsonString = new JSONObject(list).toString();
		renderJson(resp, jsonString, headers);
	}

	public List<PropertyFilter> buildPropertyFilters(final HttpServletRequest request) {
		return ActionUtils.buildPropertyFilters(request, "filter_");
	}

	public String getQuery(final List<PropertyFilter> filters) {
		return ActionUtils.buildFilterCriterions(filters);
	}

	/**
	 * 获得内容的模板
	 * 
	 * @return
	 * @throws IOException
	 */
	protected String getTemplate(String tmp, final javax.servlet.ServletContext sc) throws IOException {
		InputStream in = sc.getResourceAsStream(tmp);
		StringBuffer template = new StringBuffer(512);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			do {
				String line = reader.readLine();
				if (line == null)
					break;
				template.append(line);
				template.append("\r\n");
			} while (true);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {
				}
			}
			if (reader != null) {
				try {
					reader.close();
				} catch (Exception e) {
				}
			}
		}
		return template.toString();
	}
}
